package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;

import com.sky.result.PageResult;
import com.sky.service.ICategoryService;
import com.sky.service.ISetmealDishService;
import com.sky.service.ISetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 套餐 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-05-18
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements ISetmealService {


    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private ISetmealDishService setmealDishService;
    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private ICategoryService categoryService;

    /**
     * 新增套餐，同时需要保存套餐和菜品的关联关系
     *
     * @param setmealDTO
     */
    @Override
    @Transactional
    public void saveWithDish(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        //1.将DTO中的数据拷贝到Setmeal对象中
        BeanUtil.copyProperties(setmealDTO, setmeal);
        //2.修改人和创建人的id
        setmeal.setCreateUser(BaseContext.getCurrentId());
        setmeal.setUpdateUser(BaseContext.getCurrentId());
        setmeal.setStatus(StatusConstant.ENABLE);
        //3. 向套餐表插入数据
        setmealMapper.insert(setmeal);

        //4. 向套餐和菜品的关联关系表中插入数据
        //4.1 获取套餐id
        Long setmealId = setmeal.getId();
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)) {
            ArrayList<SetmealDish> list = new ArrayList<>();
            for (SetmealDish setmealDish : setmealDishes) {
                //4.2 设置套餐id
                setmealDish.setSetmealId(setmealId);
                list.add(setmealDish);

            }

            //5.批量插入套餐和菜品的关联关系数据
            setmealDishService.saveBatch(list);
        }


    }

    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        //1.查询当前页码和每页记录数
        int page = setmealPageQueryDTO.getPage();//当前页码
        int pageSize = setmealPageQueryDTO.getPageSize();//每页记录数

        //2.创建分页对象
        Page<SetmealVO> p = new Page<>(page, pageSize);
        //3.构造分页查询条件
        QueryWrapper<Setmeal> wrapper = new QueryWrapper<>();
        if (setmealPageQueryDTO.getName() != null && !"".equals(setmealPageQueryDTO.getName())) {
            wrapper.like("s.name", setmealPageQueryDTO.getName());
        }
        if (setmealPageQueryDTO.getCategoryId() != null) {
            wrapper.eq("s.category_id", setmealPageQueryDTO.getCategoryId());
        }
        if (setmealPageQueryDTO.getStatus() != null) {
            wrapper.eq("s.status", setmealPageQueryDTO.getStatus());
        }
        wrapper.orderByDesc("s.update_time");

        //调用mapper层的方法进行分页查询
        Page<SetmealVO> pageResult = setmealMapper.list(p, wrapper);
        return new PageResult(pageResult.getTotal(), pageResult.getRecords());

    }

    //- 可以一次删除一个套餐，也可以批量删除套餐
    //- 起售中的套餐不能删除
    @Override
    public void deleteBatch(List<Long> ids) {
        //1.查询套餐是否起售
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId, ids);
        List<Setmeal> setmeals = this.list(queryWrapper);
        for (Setmeal setmeal : setmeals) {
            if (setmeal.getStatus() == StatusConstant.ENABLE) {
                throw new DeletionNotAllowedException("套餐正在售卖中，不能删除");
            }
        }
        //2.删除套餐以及套餐和菜品的关联表中的数据
        //2.1删除套餐中的数据
        setmealMapper.deleteBatchIds(ids);
        //2.2删除套餐菜品关系表中的数据
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getSetmealId, ids);
        setmealDishMapper.delete(wrapper);

    }

    /**
     * 根据id查询套餐和关联的菜品数据
     *
     * @param id
     * @return
     */
    @Override
    public SetmealVO getByIdWithDish(Long id) {

        //1.根据id查询套餐数据

        Setmeal setmeal = setmealMapper.selectById(id);

        //2.根据套餐id查询套餐菜品关系表中的数据
        LambdaQueryWrapper<SetmealDish> wrapper1 = new LambdaQueryWrapper<>();

        wrapper1.eq(SetmealDish::getSetmealId, id);
        //得到了套餐菜品关系表中的数据
        List<SetmealDish> setmealDishes = setmealDishMapper.selectList(wrapper1);

        //4.封装数据
        SetmealVO setmealVO = new SetmealVO();
        BeanUtil.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);
        return setmealVO;
    }

    @Override
    @Transactional
    public void updateSetmeal(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtil.copyProperties(setmealDTO, setmeal);
        //1.先修改套餐表中的数据
        this.updateById(setmeal);
        //2.修改套餐表中的更新人id
        setmeal.setUpdateUser(BaseContext.getCurrentId());

        setmeal.setUpdateTime(new Date());
        //3.根据套餐id删除套餐菜品关系表中的数据
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId, setmeal.getId());
        setmealDishMapper.delete(wrapper);

        //4.添加套餐菜品关系表中的数据
        //4.1获取套餐菜品关系表中的数据
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)) {
            ArrayList<SetmealDish> list = new ArrayList<>();
            for (SetmealDish setmealDish : setmealDishes) {
                //4.2设置套餐id
                setmealDish.setSetmealId(setmeal.getId());
                list.add(setmealDish);
            }
            setmealDishService.saveBatch(list);
        }
    }

    /*
          - 起售的套餐可以展示在用户端，停售的套餐不能展示在用户端
          -起售套餐时，如果套餐内包含停售的菜品，则不能起售
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        //起售套餐时，判断套餐内是否有停售菜品，有停售菜品提示"套餐内包含未启售菜品，无法启售"
        if (status == StatusConstant.ENABLE) {

            //根据套餐id查询套餐菜品关系表中的数据
            LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SetmealDish::getSetmealId, id);
            //得到套餐菜品关系表中的数据
            List<SetmealDish> setmealDishList = setmealDishMapper.selectList(wrapper);
            if (!CollectionUtils.isEmpty(setmealDishList)) {
                for (SetmealDish setmealDish : setmealDishList) {
                    //根据菜品id查询菜品表中的数据
                    Dish dish = dishMapper.selectById(setmealDish.getDishId());
                    if (dish.getStatus() == StatusConstant.DISABLE) {
                        //如果菜品是停售的，则不能起售套餐
                        throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }

                }
            }

        }
        //套餐内没有停售菜品，则可以起售
        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .updateUser(BaseContext.getCurrentId())
                .build();
        setmealMapper.updateById(setmeal);
    }

    @Override
    public List<DishItemVO> getishItemById(Long id) {

        return setmealMapper.getishItemById(id);


    }


}
